package org.example.service;

import com.alibaba.nls.client.protocol.NlsClient;
import com.alibaba.nls.client.protocol.OutputFormatEnum;
import com.alibaba.nls.client.protocol.tts.SpeechSynthesizer;
import com.alibaba.nls.client.protocol.tts.SpeechSynthesizerListener;
import com.alibaba.nls.client.protocol.tts.SpeechSynthesizerResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;

@Service
public class SpeechService {
    private static final Logger logger = LoggerFactory.getLogger(SpeechService.class);

    @Value("${nlk.aliyun.tts.app-key}")
    private String appKey;

    @Autowired
    private NlsClient nlsClient;

    public byte[] synthesizeSpeech(String text) {

        if (text == null || text.trim().isEmpty()) {
            logger.warn("Empty text for speech synthesis");
            return new byte[0];
        }

        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

        try {
            SpeechSynthesizer synthesizer = new SpeechSynthesizer(nlsClient,
                    genSpeechSynthesizerListener(outputStream));
            synthesizer.setFormat(OutputFormatEnum.WAV);
            synthesizer.setAppKey(appKey);
            synthesizer.setSampleRate(16000);
            synthesizer.setVolume(50);
            // 调整语音合成参数以改善断句
            synthesizer.setPitchRate(0); // 保持正常音调
            synthesizer.setSpeechRate(-50); // 稍微降低语速，让语音更清晰
            // 可选播报员
            // https://help.aliyun.com/zh/isi/developer-reference/overview-of-speech-synthesis
            synthesizer.setVoice("zhishuo");

            synthesizer.setLongText(text);

            synthesizer.start();

            // 等待语音合成结束
            synthesizer.waitForComplete();
            return outputStream.toByteArray();
        } catch (Exception e) {
            logger.error("Speech synthesis failed", e);
            return new byte[0];
        }
    }

    private SpeechSynthesizerListener genSpeechSynthesizerListener(final ByteArrayOutputStream outputStream) {
        return new SpeechSynthesizerListener() {

            private boolean firstRecvBinary = true;

            @Override
            public void onComplete(SpeechSynthesizerResponse response) {
            }

            @Override
            public void onMessage(ByteBuffer message) {
                try {
                    if (firstRecvBinary) {
                        // 此处是计算首包语音流的延迟，收到第一包语音流时，即可以进行语音播放，以提升响应速度(特别是实时交互场景下)
                        firstRecvBinary = false;
                    }
                    byte[] bytesArray = new byte[message.remaining()];
                    message.get(bytesArray, 0, bytesArray.length);
                    // System.out.println("write array:" + bytesArray.length);
                    outputStream.write(bytesArray);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onFail(SpeechSynthesizerResponse response) {
                logger.error("Speech synthesis failed: {}", response.getStatusText());
            }
        };
    }
}